package com.core.springSecurity.service;

import com.common.utils.Constants;
import com.common.ErrorCodeEnum;
import com.common.exception.BusinessException;
import com.common.redis.RedisCache;
import com.common.utils.StringUtils;
import com.common.utils.uuid.IdUtils;
import com.core.springSecurity.common.ImageUtil;
import com.core.springSecurity.model.Unlock;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.File;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @Author: zql
 * @Description: 滑块验证码服务
 * @Data: 11:14 2021/4/30
 */
@Slf4j
@Service
public class UnlockService {
    @Resource
    private RedisCache redisCache;

    boolean init = false;
    /**图片列表*/
    File[] files;

    @Value("${unlock.imagePath:/unlockImage}")
    private String imagePath;

    @Value("${unlock.enable:false}")
    private boolean enable;

    /** 滑块图片有效期 （单位:分钟）*/
    @Value("${unlock.expireTime:5}")
    private int expireTime;

    /** 滑块通过密钥有效期（单位:分钟） */
    @Value("${unlock.keyExpireTime:20}")
    private int keyExpireTime;

    @PostConstruct
    private void init() throws BusinessException {
        log.info("滑块服务:{}", enable);
        if(enable) {
            File file = new File(System.getProperty("user.dir")+imagePath);
            files = file.listFiles();
        }
        init = true;
    }

    /**
     * @Author: zql
     * @Description: 创建拼图验证码
     * @Data: 11:18 2021/4/30
     */
    public Unlock createImage() {
        if (!enable) {
            log.warn("滑块服务未启动，创建拼图验证码失败");
            throw new BusinessException(ErrorCodeEnum.UNLOCK_STOP);
        }

        //读取本地路径下的图片,随机选一条
        int n = new Random().nextInt(files.length);
        File file = files[n];

        Unlock unlock = ImageUtil.createImage(file);
        unlock.setUnlockImageId(IdUtils.simpleUUID());
        String imageKey = getImageKey(unlock.getUnlockImageId());
        redisCache.setCacheObject(imageKey, unlock.getWidthRandom(), expireTime, TimeUnit.MINUTES);

        return unlock;
    }

    public String verifyImageCode(String unlockImageId,Double dMoveLength,String defaultReturn){
        if(!enable){
            log.warn("滑块服务未启动，创建拼图验证码失败");
            return "true";
        }
        String imageKey = getImageKey(unlockImageId);
        try {
            Integer xWidth = redisCache.getCacheObject(imageKey);
            if (StringUtils.isNull(xWidth)) {
                return defaultReturn;
            }
            //验证容错10
            if (Math.abs(xWidth - dMoveLength) > 10) {
                return defaultReturn;
            } else {
                //验证通过删除该滑块图片记录并生成登录用的key
                redisCache.deleteObject(imageKey);
                return createUnlockLogin();
            }
        } catch (Exception e) {
            return defaultReturn;
            // throw new EsServiceException(e.getMessage());
        }
    }

    public String createUnlockLogin(){
        String unlockLogin = IdUtils.simpleUUID();
        String unlockLoginKey = getUnlockLoginKey(unlockLogin);
        redisCache.setCacheObject(unlockLoginKey, "success", keyExpireTime, TimeUnit.MINUTES);
        return unlockLogin;
    }

    public boolean verifyUnlockLogin(String unlockLogin) {
        if(!enable){
            log.warn("滑块服务未启动,滑块校验结果直接返回true");
            return true;
        }
        String unlockLoginKey = getUnlockLoginKey(unlockLogin);
       String value =redisCache.getCacheObject(unlockLoginKey);
       if(StringUtils.isEmpty(value)){
            return false;
       }
        redisCache.deleteObject(unlockLoginKey);
        return true;
    }

    public String getImageKey(String uuid) {
        return Constants.UNLOCK_IMAGE_KEY + uuid;
    }
    private String getUnlockLoginKey(String uuid) {
        return Constants.UNLOCK_LOGIN_KEY + uuid;
    }
}
